package com.example.test;

import java.util.ArrayList;
import java.util.HashMap;

import android.R.integer;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.Toast;

public class PlayGround extends SurfaceView implements OnTouchListener {

	

	private static final int H = 7;
	private static final int L = 7;
	private static int WIDTH = 40;
	private static int BLOCKS = 8;
	private Dot[][] mMatix = null;
	private Dot cat = null;
	private int step;
	private TouchUp mTouchUp;
	public PlayGround(Context context) {
		super(context);
		init();
	}
	public PlayGround(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}
	
	private void init() {
		getHolder().addCallback(callback);
		mMatix = new Dot[H][L];
		for (int i = 0; i < H; i++) {
			for (int j = 0; j < L; j++) {
				mMatix[i][j] = new Dot(j, i);// 点的x应该是列数
			}
		}
		initData();
		setOnTouchListener(this);
	}
	
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int speSize = MeasureSpec.getSize(widthMeasureSpec);
        int speMode = MeasureSpec.getMode(heightMeasureSpec);
        
        setMeasuredDimension(speSize, speSize);
	}

	public void initData() {
		step=0;
		for (int i = 0; i < H; i++) {
			for (int j = 0; j < L; j++) {
				mMatix[i][j].setStatus(Dot.STATUS_OFF);
			}
		}
		cat = new Dot(3, 4);
		getDot(cat.getX(), cat.getY()).setStatus(Dot.STATUS_IN);// 猫
		for (int i = 0; i < BLOCKS;) {// 设置路障
			int x = (int) (Math.random() * 1000 % H);
			int y = (int) (Math.random() * 1000 % L);
			if (getDot(x, y).getStatus() == Dot.STATUS_OFF) {
				getDot(x, y).setStatus(Dot.STATUS_ON);
				i++;
			}
		}
	}

	public void redraw() {
		Canvas canvas = getHolder().lockCanvas();
		canvas.drawColor(Color.LTGRAY);
		Paint paint = new Paint();
		paint.setFlags(Paint.ANTI_ALIAS_FLAG);
		for (int i = 0; i < H; i++) {
			int offest = 0;
			if (i % 2 != 0) {
				offest = WIDTH / 2;
			}
			for (int j = 0; j < L; j++) {
				Dot dot = getDot(j, i);
				switch (dot.getStatus()) {
				case Dot.STATUS_OFF:
					paint.setColor(0xFFEEEEEE);
					break;
				case Dot.STATUS_ON:
					paint.setColor(0xFFFFAA00);

					break;
				case Dot.STATUS_IN:
					paint.setColor(0xFFFF0000);

					break;

				default:
					break;
				}
				canvas.drawOval(
						new RectF(dot.getX() * WIDTH + offest, dot.getY()
								* WIDTH, (dot.getX() + 1) * WIDTH + offest,
								(dot.getY() + 1) * WIDTH), paint);
			}
		}
		getHolder().unlockCanvasAndPost(canvas);
	}

	private Dot getDot(int x, int y) {
		return mMatix[y][x];
	}

	Callback callback = new Callback() {

		@Override
		public void surfaceDestroyed(SurfaceHolder holder) {
			// TODO Auto-generated method stub

		}

		@Override
		public void surfaceCreated(SurfaceHolder holder) {
			redraw();
		}

		@Override
		public void surfaceChanged(SurfaceHolder holder, int format, int width,
				int height) {
			WIDTH = width / (H + 1);
			redraw();
		}
	};

	@Override
	public boolean onTouch(View v, MotionEvent event) {
		if (event.getAction() == MotionEvent.ACTION_UP) {
			int x, y;
			y = (int) (event.getY() / WIDTH);
			if (y % 2 == 0) {
				x = (int) (event.getX() / WIDTH);
			} else {
				x = (int) ((event.getX() - WIDTH / 2) / WIDTH);
			}
			if (x + 1 > H || y + 1 > L) {
				initData();
			} else if (getDot(x, y).getStatus() == Dot.STATUS_OFF) {
				getDot(x, y).setStatus(Dot.STATUS_ON);
				move();
			}

			redraw();
			step++;
			if (mTouchUp!=null) {
				mTouchUp.up();
			}
		}
		return true;
	}

	public interface TouchUp{
		public void up();
	}
	
	
	
	public void setTouchUp(TouchUp mTouchUp) {
		this.mTouchUp = mTouchUp;
	}
	/**
	 * 
	 * @param one
	 * @param dir
	 *            方向，从1到6
	 * @return
	 */
	public Dot getNeighboor(Dot one, int dir) {
		switch (dir) {
		case 1:
			return getDot(one.getX() - 1, one.getY());
		case 2:
			if (one.getY() % 2 == 0) {
				return getDot(one.getX() - 1, one.getY() - 1);
			} else {
				return getDot(one.getX(), one.getY() - 1);
			}
		case 3:

			if (one.getY() % 2 == 0) {
				return getDot(one.getX(), one.getY() - 1);
			} else {
				return getDot(one.getX() + 1, one.getY() - 1);
			}
		case 4:
			return getDot(one.getX() + 1, one.getY());
		case 5:

			if (one.getY() % 2 == 0) {
				return getDot(one.getX(), one.getY() + 1);
			} else {
				return getDot(one.getX() + 1, one.getY() + 1);
			}
		case 6:

			if (one.getY() % 2 == 0) {
				return getDot(one.getX() - 1, one.getY() + 1);
			} else {
				return getDot(one.getX(), one.getY() + 1);
			}

		default:
			break;
		}
		return null;
	}

	public boolean isAtEdge(Dot one) {
		if (one.getX() * one.getY() == 0 || one.getX() == H - 1
				|| one.getY() == L - 1) {
			return true;
		}
		return false;
	}

	/**
	 * 还有几个就可以出去 如果在边缘是1个，如果方向邻居上被不能出则是 0或是负的多少个，能出去则还差多少个
	 * 
	 * @param one
	 * @param dir
	 * @return
	 */
	public int getDistance(Dot one, int dir) {

		int distance = 0;
		Dot origal = one, next;
		if (isAtEdge(one)) {
			return 1;
		}
		while (true) {
			next = getNeighboor(origal, dir);
			if (next.getStatus() == Dot.STATUS_ON) {
				return distance * -1;
			}
			if (isAtEdge(next)) {
				distance++;
				return distance;
			}
			distance++;
			origal = next;
		}
	}

	private void moveTo(Dot one) {
		one.setStatus(Dot.STATUS_IN);
		getDot(cat.getX(), cat.getY()).setStatus(Dot.STATUS_OFF);
		cat.setX(one.getX());
		cat.setY(one.getY());
	}

	public void move() {
		if (isAtEdge(cat)) {
			lose();
			return;
		}
		ArrayList<Dot> avilable = new ArrayList<Dot>();
		HashMap<Dot, Integer> map = new HashMap<Dot, Integer>();
		ArrayList<Dot> positive = new ArrayList<Dot>();
		for (int i = 1; i < 7; i++) {
			Dot nei = getNeighboor(cat, i);
			if (nei.getStatus() == Dot.STATUS_OFF) {
				avilable.add(nei);
				map.put(nei, i);
				if (getDistance(nei, i) > 0) {
					positive.add(nei);
				}
			}
		}

		if (avilable.size() == 0) {
			win();
		} else if (avilable.size() == 1) {
			moveTo(avilable.get(0));
		} else {
			Dot best = null;
			if (positive.size() != 0) {// 存在可以直接到达屏幕边缘的走向
				System.out.println("向前进");
				int min = 999;
				for (int i = 0; i < positive.size(); i++) {
					int a = getDistance(positive.get(i),
							map.get(positive.get(i)));
					if (a < min) {
						min = a;
						best = positive.get(i);
					}
				}
				moveTo(best);
			} else {// 所有方向都存在路障
				System.out.println("躲路障");
				int max = 0;
				for (int i = 0; i < avilable.size(); i++) {
					int k = getDistance(avilable.get(i),
							map.get(avilable.get(i)));
					if (k <= max) {
						max = k;
						best = avilable.get(i);
					}
				}
				moveTo(best);
			}
		}

	}

	private void lose() {
		Toast.makeText(getContext(), "lose", Toast.LENGTH_SHORT).show();

	}

	private void win() {
		Toast.makeText(getContext(), "win", Toast.LENGTH_SHORT).show();

	}
	public int getStep() {
		return step;
	}
	public void setStep(int step) {
		this.step = step;
	}
	
	

}
